﻿using System.Collections.Generic;
using UnityEngine;
using System;
using System.IO;
using System.Linq;
using XLua;

public partial class LuaBehaviour
{
    static LuaEnv mLuaEnvInstance;
    static List<LuaFileLoaderBase> loaders = new List<LuaFileLoaderBase>();
    public static LuaEnv LuaEnvInstance
    {
        get
        {
            if(mLuaEnvInstance == null)
            {
                mLuaEnvInstance = new LuaEnv();
                InitLoaders(LuaEnvInstance);
            }
            return mLuaEnvInstance;
        }
    }
    
    public static byte[] GetLuaFile(ref string fileName)
    {
        foreach (var loader in loaders)
        {
            var data = loader.LoadFunction(ref fileName);
            if (data != null)
            {
                return data;
            }
        }
        Debug.LogError("Lua file not found: " + fileName + "\n searchPath: " +
                       string.Join(";", loaders.Select(x => x.SearchPath)));
        return null;
    }
    
    public  static void InitLoaders(LuaEnv luaEnv)
    {
        loaders.Clear();
        loaders.Add(new LuaFileLoaderBase());
        //loader
        var cnfType = typeof(LuaFileLoaderBase);
        var cnfs = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
                where assembly.FullName.Contains("Assembly-CSharp")
                from type in assembly.GetExportedTypes()
                where type.IsSubclassOf(cnfType)
                select type);
        if (cnfs != null)
        {
            foreach (Type type in cnfs)
                loaders.Add(Activator.CreateInstance(type) as LuaFileLoaderBase);
        }
        if(luaEnv != null)
            luaEnv.AddLoader(GetLuaFile);
    }


    public static List<string> SearchPaths
    {
        get
        {
            List<string> path = new List<string>();
            foreach (var loader in loaders)
            {
                foreach (var p in loader.SearchPath)
                {
                    var fp = Path.GetFullPath(p);
                    if(Directory.Exists(fp))
                        path.Add(fp);
                }
            }
            return path;
        }
    }
}



public class LuaFileLoaderBase
{
    public List<string> SearchPath = new List<string>
    {
        "Packages/luabehaviour.unity/Lua/",
    };
    //通过路径加载lua文件
    public  virtual byte[] LoadFunction(ref string fileName)
    {
        if (!fileName.EndsWith(".lua", StringComparison.Ordinal))
        {
            fileName = fileName.Replace('.', '/');
            fileName += ".lua";
        }
        else
        {
            fileName = fileName.Replace('.', '/').Replace("/lua", ".lua");
        }
#if UNITY_EDITOR
        var LuaPath = Path.GetFullPath(SearchPath[0]);
        var path = Path.Combine(LuaPath, fileName);
        if (File.Exists(path))
            return File.ReadAllBytes(path);
        return null;
#else
        var path = Path.Combine("Assets/LuaBundle/", fileName);
        path += ".bytes";
        var assetBundle = AssetBundleManagerForLua.LuaAssetBundle;        
        var luaAsset = assetBundle.LoadAsset<TextAsset>(path);
        return luaAsset.bytes;
#endif
    }
    
}